package com.youlu.campus.web.order.controller;

import com.youlu.campus.base.order.vo.OrderRequest;
import com.youlu.campus.entity.DeliveryOrderSubMsg;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.VO.PlaceOrderReq;
import com.youlu.campus.entity.VO.req.OrderUpdateRestReq;
import com.youlu.campus.entity.domain.ModifyAddressDomain;
import com.youlu.campus.entity.domain.RefundDomain;
import com.youlu.campus.service.activity.UserParticipateActivityInfoService;
import com.youlu.campus.service.notify.KuaiDi100Service;
import com.youlu.campus.service.order.DeliveryOrderSubMsgService;
import com.youlu.campus.service.order.LogisticsOrderService;
import com.youlu.campus.service.order.OrderUpdateRestService;
import com.youlu.campus.web.common.base.RequestContext;
import com.youlu.campus.web.order.entity.vo.AddressVO;
import com.youlu.campus.web.order.service.AddressService;
import com.youlu.campus.web.order.service.OrderService;
import com.youlu.campus.web.order.service.pay.PayService;
import com.yuelin.infrastructure.quantum.common.QResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单相关控制器
 * 处理订单管理、地址管理、支付相关及物流查询等操作
 *
 * @author zgz
 * @date 2020/8/8 16:20
 */
@RestController
@Slf4j
public class OrderController {
    @Autowired
    private AddressService addressService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private PayService payService;
    @Autowired
    private KuaiDi100Service kuaiDi100Service;

    @Autowired
    private DeliveryOrderSubMsgService deliveryOrderSubMsgService;

    @Autowired
    private OrderService orderPayService;

    @Autowired
    private UserParticipateActivityInfoService userParticipateActivityInfoService;

    @Autowired
    private OrderUpdateRestService orderUpdateRestService;
    @Lazy
    @Autowired
    private LogisticsOrderService logisticsOrderService;

    /**
     * 用户收货地址添加
     * 添加新的用户收货地址信息
     *
     * @param addressVO 地址信息VO，包含收货人、电话、地址等
     * @return 添加结果
     */
    @PostMapping("/mini-app/user/address/add")
    public QResult addAddress(@RequestBody @Valid AddressVO addressVO) {
        return QResult.success(addressService.addAddress(addressVO));
    }

    /**
     * 用户收货地址列表
     * 查询当前用户的所有收货地址
     *
     * @return 收货地址列表
     */
    @GetMapping("/mini-app/user/addresses")
    public QResult getAddress() {
        return QResult.success(addressService.getUserAddress(RequestContext.getUserId()));
    }

    /**
     * 删除用户收货地址
     * 根据地址ID删除当前用户的指定收货地址
     *
     * @param id 地址ID
     * @return 删除结果
     */
    @GetMapping("/mini-app/user/address/delete")
    public QResult deleteAddress(@RequestParam("id") String id) {
        return QResult.success(addressService.deleteUserAddress(RequestContext.getUserId(), id));
    }

    /**
     * 下单操作
     * 创建新的订单
     *
     * @param req 下单请求参数，包含商品、地址等信息
     * @return 下单结果
     */
    @PostMapping("/mini-app/order/place")
    public QResult placePaperOrder(@RequestBody @Valid PlaceOrderReq req) {
        return QResult.success(orderService.placeOrder(req));
    }

    /**
     * 查询订单支付状态
     * 检查指定订单的支付状态
     *
     * @param orderNo 订单编号
     * @return 支付状态（成功/失败）
     */
    @GetMapping("/mini-app/order/pay-status")
    public QResult getOrderPayStatus(@RequestParam("orderNo") String orderNo) {
        boolean res = orderService.getOrderPayStatus(orderNo);
        if (res) {
            return QResult.success("支付成功");
        }
        return QResult.fail("支付失败");
    }

    /**
     * 用户订单列表
     * 分页查询当前用户的订单列表
     *
     * @param request 订单查询请求参数，包含分页和筛选条件
     * @return 订单列表数据
     */
    @PostMapping("/mini-app/user/order/list")
    public QResult getUserOrderList(@RequestBody @Valid OrderRequest request) {
        request.setAppId(RequestContext.getAppId());
        request.setPlatform(RequestContext.getCurPlatform());
        return QResult.success(orderService.getUserOrderList(request));
    }

    /**
     * 微信支付回调处理
     * 接收微信支付平台的支付结果回调并处理
     *
     * @param content 回调内容（XML格式）
     * @return 回调响应（XML格式）
     */
    @RequestMapping("/public/wx/payNotify")
    public String payWxNotify(@RequestBody String content) {
        log.info(":>>> 收到微信支付回调:{}", content);
        String result = payService.payNotify(content);
        return "<xml>\n" +
                "  <return_code><![CDATA[" + result + "]]></return_code>\n" +
                "</xml>";
    }

    /**
     * 获取待修改的地址详情
     * 根据地址ID查询地址详情，用于修改操作
     *
     * @param id 地址ID
     * @return 地址详情
     */
    @GetMapping("/mini-app/user/address/modify/find-one")
    public QResult getModifyAddressDetail(@RequestParam("id") String id) {
        return QResult.success(orderService.getModifyAddressDetail(id));
    }

    /**
     * 修改地址详情
     * 更新用户的收货地址信息
     *
     * @param request 地址修改请求参数
     * @return 修改结果
     */
    @PostMapping("/mini-app/user/address/modify")
    public QResult modifyAddressDetail(@RequestBody @Valid ModifyAddressDomain request) {
        return QResult.success(orderService.modifyAddressDetail(request));
    }

    /**
     * 获取退款详情
     * 查询指定订单的退款详情信息
     *
     * @param id 订单ID
     * @return 退款详情
     */
    @GetMapping("/mini-app/order/refund/find-one")
    public QResult getRefundDetail(@RequestParam("id") String id) {
        return QResult.success(orderService.getRefundDetail(id, RequestContext.getUserId()));
    }

    /**
     * 申请退款
     * 提交订单退款申请
     *
     * @param request 退款请求参数，包含退款原因等信息
     * @return 退款申请结果
     */
    @PostMapping("/mini-app/order/refund")
    public QResult refund(@RequestBody @Valid RefundDomain request) {
        request.setRefundApplyUserType("visitor");
        request.setRefundApplyPlatform(RequestContext.getCurPlatform());
        request.setRefundApplyAppId(RequestContext.getAppId());
        request.setUserId(RequestContext.getCurUserId());
        return QResult.success(orderService.refund(request));
    }

    /**
     * 查询物流轨迹
     * 根据订单号查询物流跟踪信息
     *
     * @param orderNo 订单编号
     * @return 物流轨迹信息
     */
    @GetMapping("/mini-app/order/track")
    public QResult subscribe(@RequestParam String orderNo) {
        return QResult.success(kuaiDi100Service.queryTrack(orderNo));
    }

    /**
     * 保存订单发货订阅消息
     * 保存用户对订单发货通知的订阅信息
     *
     * @param deliveryOrderSubMsg 发货订阅消息实体
     * @return 保存结果
     */
    @PostMapping("/mini-app/order/delivery/sub-msg")
    public QResult deliveryOrderSubMsg(@RequestBody DeliveryOrderSubMsg deliveryOrderSubMsg) {
        UserPO curUser = RequestContext.getCurUser();
        deliveryOrderSubMsg.setOpenId(curUser.getOpenId());
        deliveryOrderSubMsg.setUserId(curUser.getId());
        deliveryOrderSubMsg.setAppId(curUser.getAppId());
        deliveryOrderSubMsgService.saveOrderSubMsg(deliveryOrderSubMsg);
        return QResult.success(null);
    }

    /**
     * 初始化测试订单订阅
     * 用于测试的订单订阅初始化操作
     *
     * @return 操作结果
     */
    @GetMapping("/public/order/delivery/sub-msg/init")
    public QResult subscribeOrder() {
        deliveryOrderSubMsgService.initTestSubOrder();
        return QResult.success(null);
    }

    /**
     * 根据订单推荐活动
     * 根据用户订单信息推荐相关活动
     *
     * @param orderNo 订单编号
     * @return 推荐活动列表
     */
    @GetMapping("/mini-app/order/activity-recommend")
    public QResult recommend(@RequestParam String orderNo) {
        return QResult.success(orderService.findActivityRecommendByOrderNo(RequestContext.getCurUser(), orderNo));
    }

    /**
     * 处理订单提示
     * 按时间范围处理订单提示信息
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     */
    @GetMapping("/public/order/handle/tips")
    public void orderTips(@RequestParam("startTime") String startTime,
                          @RequestParam("endTime") String endTime) {
        orderService.handleOrderTips(startTime, endTime);
    }

    /**
     * 初始化报名缓存
     * 初始化活动报名相关的缓存数据
     *
     * @param activityId 活动ID（可选）
     * @return 操作结果
     */
    @GetMapping("/public/init/sign/up")
    public QResult signUpInit(@RequestParam(value = "activityId", required = false) String activityId) {
        userParticipateActivityInfoService.signUpInitCache(activityId);
        return QResult.success(null);
    }

    /**
     * 更新订单库存
     * 处理订单相关的库存更新操作
     *
     * @param req 订单库存更新请求参数
     * @return 操作结果
     */
    @PostMapping("/public/order/rest")
    public QResult orderUpdateRest(@RequestBody OrderUpdateRestReq req) {
        orderUpdateRestService.doUpdateRest(req);
        return QResult.success(null);
    }

    /**
     * 获取物流详情
     * 查询指定订单的物流详细信息
     *
     * @param orderId 订单ID
     * @return 物流详情
     */
    @GetMapping("/mini-app/order/logistics-detail")
    public QResult logisticsDetail(@RequestParam String orderId) {
        return QResult.success(logisticsOrderService.getLogisticsOrderDetail(orderId));
    }

    /**
     * 获取物流查询模式
     * 查询当前平台的物流查询模式配置
     *
     * @return 物流查询模式信息
     */
    @GetMapping("/mini-app/order/query-mode")
    public QResult orderQueryMode() {
        return QResult.success(logisticsOrderService.orderQueryMode(RequestContext.getCurPlatform()));
    }

    /**
     * 同步证书编号（内部接口）
     * 按时间范围同步订单的证书编号信息，需验证密码
     *
     * @param startTime  开始时间戳
     * @param endTime    结束时间戳
     * @param batchId    批次ID
     * @param pw         访问密码
     * @param orderNo    订单编号（可选）
     * @param activityId 活动ID（可选）
     * @return 操作结果
     */
    @PostMapping("/public/rd/syc-cano")
    public QResult sysCaNo(@RequestParam("startTime") Long startTime,
                           @RequestParam("endTime") Long endTime,
                           @RequestParam("batchId") String batchId,
                           @RequestParam("pw") String pw,
                           @RequestParam(value = "orderNo", required = false) String orderNo,
                           @RequestParam(value = "activityId", required = false) String activityId) {
        if (!"ZZhq0(!)*.&^^*&*&".equals(pw)) {
            return QResult.success("NO!!");
        }
        List<OrderInfo> orders = new ArrayList<>();
        if (StringUtils.isNotBlank(orderNo)) {
            OrderInfo orderInfo = orderService.findByOrderNo(orderNo);
            if (!Objects.isNull(orderInfo)) {
                orders.add(orderInfo);
            }
        } else {
            orders = orderService.syncCaNumber(activityId, batchId, new Date(startTime), new Date(endTime));
        }
        log.info(":>>> 批次ID:{},同步证书编号大小:{}", batchId, orders.size());
        for (OrderInfo orderInfo : orders) {
            orderService.asyncHandleUserCertificate(orderInfo.getOrderNo());
        }
        return QResult.success("OK!!");
    }

}